開放街圖,OpenStreetMap,簡稱 OSM,我們把它當成一個地圖版的維基百科。
是由世界各地多名註冊使用者協同維護網站。
那為甚麼我們要講到這個嗎?
有時候我們 Line chatbot 的應用除了爬蟲,還有爬地圖。
但是如果使用 Google API 的話,一個不小心可能就要付錢了。(怕.jpg)
所以我們可以傳送位址訊息給 Line API 來定位,或是搜尋附近的東西。
標記出固定區域內的同類型行業
Folium 是基於 leaflet.js 的 python 地圖視覺化工具套件。
可以在 jupyter 直接顯示或是輸出成 HTML。
Folium 內建許多 Open Source 的 Map:OpenStreetMap、MapQuest Open、MapQuestOpen Aerial、Mapbox 和 Stamen。而且支援使用 Mapbox 或 Cloudmade 的 API 金鑰来制定客制化的地圖元件。
由於使用 Google Map API 免費版有使用次數上的限制,也就是會記錄透過金鑰去 request API 的次數。故此專案使用完全開源的地圖 OpenStreetMap (OSM)。
pip install folium
或是
conda install -c conda-forge folium
我們來看看我們的 location message:
{
    "type": "location",
    "title": "my location",
    "address": "1-6-1 Yotsuya, Shinjuku-ku, Tokyo, 160-0004, Japan", 
    "latitude": 35.687574,
    "longitude": 139.72922
}
latitude: 緯度longitude: 經度
我們可以用這種方式回送一個地址到 Chat room,也可以透過傳送定位來接收經緯度。
例如說我們這樣:
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from linebot import LineBotApi, WebhookParser
from linebot.exceptions import InvalidSignatureError, LineBotApiError
from linebot.models import *
import os
line_bot_api = LineBotApi(settings.LINE_CHANNEL_ACCESS_TOKEN)
parser = WebhookParser(settings.LINE_CHANNEL_SECRET)
@csrf_exempt
def callback(request):
    if request.method == 'POST':
        signature = request.META['HTTP_X_LINE_SIGNATURE']
        body = request.body.decode('utf-8')
        try:
            events = parser.parse(body, signature)  # 傳入的事件
        except InvalidSignatureError:
            return HttpResponseForbidden()
        except LineBotApiError:
            return HttpResponseBadRequest()
        for event in events:
            print("event", event.message.id)
            # print("event", type(event))
            if isinstance(event, MessageEvent):  # 如果有訊息事件
                print("message", event.message)
                message = []
                if event.message.type == 'location':
                    print(event)
                    location = "latitude = {}\nlongitude = {}".format(event.message.latitude, event.message.longitude)
                    message.append(TextSendMessage(text=location))
                line_bot_api.reply_message(event.reply_token, message)
        return HttpResponse()
    else:
        return HttpResponseBadRequest()
我們在 if event.message.type == 'location': 就判定傳過的 object type 為何?如果是 location,那就顯示出當下的經緯度,也可以透過 event.message.address 印出地址。

那剩下的 OSM 應用我們留到明天再講~
你好,可以請問OpenStreetMap API是否也有次數限制嗎?
OpenStreetMap 是純開源的 沒有次數限制
好的,感謝回覆